package com.yyfax.pay.third.facade.minsheng;

import com.yyfax.pay.third.facade.lianlian.LianlianApi;
import com.yyfax.pay.third.facade.minsheng.util.MinshengUtil;
import com.yyfax.pay.third.model.to.minsheng.CheckBatchPayoutOrderMinshengContent;
import com.yyfax.pay.third.model.to.minsheng.CheckBatchPayoutOrderMinshengParams;
import com.yyfax.pay.third.model.to.minsheng.MinshengBatchPayVo;
import com.yyfax.pay.third.model.to.minsheng.PayoutOrderMinshengContent;
import com.yyfax.pay.third.model.to.minsheng.PayoutOrderMinshengParams;
import com.yyfax.pay.third.model.to.minsheng.QueryBatchPayoutOrderMinshengContent;
import com.yyfax.pay.third.model.to.minsheng.QueryBatchPayoutOrderMinshengParams;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 民生代付api
 *
 * @author AlanQiu on 2017/4/18.
 */
@Service
public class MinshengApi {

	private Logger log = LoggerFactory.getLogger(LianlianApi.class);

	public PayoutOrderMinshengContent payout(PayoutOrderMinshengParams payoutOrderMinshengParams) throws Exception {

		String host = payoutOrderMinshengParams.getHost();
		String port = payoutOrderMinshengParams.getPort();

		String header = payoutOrderMinshengParams.getHeader();
		byte[] headerBytes = header.getBytes();

		String body = payoutOrderMinshengParams.getBody();
		byte[] bodyBytes = body.getBytes("UTF-8");

		String file = payoutOrderMinshengParams.getFile();
		// int fileLength = (int) new File(file).length();

		String keys = payoutOrderMinshengParams.getKeys();
		String vis = payoutOrderMinshengParams.getVis();
		String algorithm = payoutOrderMinshengParams.getAlgorithm();

		try (Socket socket = new Socket(host, Integer.valueOf(port))) {

			int length = 0;
			OutputStream outputStream = socket.getOutputStream();

			int format_length = 0;

			byte[] format = new byte[1024 * 4];
		/* 发报文头 */
			outputStream.write(headerBytes, 0, headerBytes.length);
			log.info(headerBytes.length + ": " + new String(headerBytes));
			System.arraycopy(headerBytes, 0, format, 0, headerBytes.length);
			format_length += headerBytes.length;

		/* 发报文体 */
			outputStream.write(bodyBytes, 0, bodyBytes.length);
			log.info(bodyBytes.length + ": " + body);
			System.arraycopy(bodyBytes, 0, format, format_length, bodyBytes.length);
			format_length += bodyBytes.length;

		/* 发文件 */
			FileInputStream fileInputStream = new FileInputStream(file);
			byte[] buffer = new byte[4 * 1024];
			int tot = 0;
			while ((length = fileInputStream.read(buffer, 0, buffer.length)) != -1) {
				outputStream.write(buffer, 0, length);
				tot += length;
				log.info("length: " + length + "\ttot: " + tot);
				// System.arraycopy(buffer, 0, format, format_length, length);
				format_length += length;
			}

		/* 接收回调 */
			InputStream inputStream = socket.getInputStream();
			byte[] recvBuffer = new byte[226];
			int revlength = inputStream.read(recvBuffer);
			if (revlength == -1) {
				throw new Exception("请求民生代付环境失败！");
			}
			log.info("recv data:\n[" + new String(recvBuffer, 0, revlength, "UTF-8") + "]");

			int bodyLength = Integer.valueOf(new String(recvBuffer, 0, 8));
			int offset = Integer.valueOf(new String(recvBuffer, 26, 6));
			log.info("Body-Length: " + bodyLength);
			log.info("Offset: " + offset);

			char fileFlag = (char) recvBuffer[22];
			log.info("File-Flag: " + fileFlag);

			int formatLength = bodyLength;
			if (fileFlag == '1') {
				formatLength = offset;
			}
			log.info("Format-Length: " + formatLength);
			format = new byte[formatLength];
			inputStream.read(format);
			byte[] decryptedFormat = MinshengUtil.decrypt(format, keys, vis, algorithm);
			String recvData = new String(decryptedFormat, "UTF-8");
			log.info("民生批量代付回调报文为：{}", recvData);

			String recvDatas[] = recvData.split("\\|", -1);
			PayoutOrderMinshengContent content = new PayoutOrderMinshengContent();
			content.setBatchDate(recvDatas[0]);
			content.setBatchNo(recvDatas[1]);
			content.setBatchStat(recvDatas[2]);
			content.setMessage(recvDatas[3]);
			content.setCount(StringUtils.isBlank(recvDatas[4]) ? 0 : Integer.valueOf(recvDatas[4]));
			content.setAmount(StringUtils.isBlank(recvDatas[5]) ? 0 : new Double(recvDatas[5]));

			content.setRequestUrl(host + ":" + port);
			content.setRequestFile(file);
			content.setResponseFile("");

			return content;
		}
	}

	public QueryBatchPayoutOrderMinshengContent queryPayout(QueryBatchPayoutOrderMinshengParams queryBatchPayoutOrderMinshengParams)
			throws Exception {
		String host = queryBatchPayoutOrderMinshengParams.getHost();
		String port = queryBatchPayoutOrderMinshengParams.getPort();

		String header = queryBatchPayoutOrderMinshengParams.getHeader();
		byte[] headerBytes = header.getBytes();

		String body = queryBatchPayoutOrderMinshengParams.getBody();
		byte[] bodyBytes = body.getBytes("UTF-8");

		String keys = queryBatchPayoutOrderMinshengParams.getKeys();
		String vis = queryBatchPayoutOrderMinshengParams.getVis();
		String algorithm = queryBatchPayoutOrderMinshengParams.getAlgorithm();

		byte[] keyBytes = MinshengUtil.hex2bin(keys);

		Socket socket = new Socket(host, Integer.valueOf(port));

		int length = 0;
		OutputStream outputStream = socket.getOutputStream();

		byte[] format = new byte[1024 * 4];
		int format_length = 0;

		// 发报文头
		outputStream.write(headerBytes, 0, headerBytes.length);
		log.info(headerBytes.length + ": " + new String(headerBytes));
		System.arraycopy(headerBytes, 0, format, 0, headerBytes.length);
		format_length += headerBytes.length;

		// 发报文体
		outputStream.write(bodyBytes, 0, bodyBytes.length);
		log.info(bodyBytes.length + ": " + body);
		System.arraycopy(bodyBytes, 0, format, format_length, bodyBytes.length);
		format_length += bodyBytes.length;

		// 接收回调
		InputStream inputStream = socket.getInputStream();
		byte[] recvBuffer = new byte[226];
		length = inputStream.read(recvBuffer, 0, 226);
		log.info("recv data:\n[" + new String(recvBuffer, 0, length, "UTF-8") + "]");

		int bodyLength = Integer.valueOf(new String(recvBuffer, 0, 8));
		int offset = Integer.valueOf(new String(recvBuffer, 26, 6));
		log.info("Body-Length: " + bodyLength);
		log.info("Offset: " + offset);

		byte[] dt = new byte[14];
		System.arraycopy(recvBuffer, 32, dt, 0, 14);
		log.info("Time: " + new String(dt));

		byte[] recvAll = new byte[bodyLength];
		int recvd_length = 0;

		byte buffer[] = new byte[1024];
		while (recvd_length < bodyLength) {
			length = inputStream.read(buffer, 0, 1024);
			System.arraycopy(buffer, 0, recvAll, recvd_length, length);
			recvd_length += length;
			log.info("length: " + length + "\trecvd_length: " + recvd_length);
		}

		char fileFlag = (char) recvBuffer[22];
		log.info("File-Flag: " + fileFlag);

		int formatLength = bodyLength;

		// 文件标识
		if (fileFlag == '1') {
			formatLength = offset;
		}

		format = new byte[formatLength];
		// inputStream.read(format);
		System.arraycopy(recvAll, 0, format, 0, formatLength);
		byte[] decryptedFormat = MinshengUtil.decrypt(format, keys, vis, algorithm);
		String recvData = new String(decryptedFormat, "UTF-8");
		log.info("民生批量代付回调报文为：" + recvData);

		String recvDatas[] = recvData.split("\\|", -1);

		byte[] toMD5 = new byte[24 + 14 + decryptedFormat.length];
		System.arraycopy(keyBytes, 0, toMD5, 0, keyBytes.length);
		System.arraycopy(dt, 0, toMD5, 24, 14);
		System.arraycopy(decryptedFormat, 0, toMD5, 38, decryptedFormat.length);

		List<MinshengBatchPayVo> lists = new ArrayList<MinshengBatchPayVo>();

		if (fileFlag == '1') {
			int file_length = bodyLength - offset;
			byte[] file = new byte[file_length];
			System.arraycopy(recvAll, offset, file, 0, file_length);

			file = MinshengUtil.decrypt(file, keys, vis, algorithm);
			String fileContent = new String(file, "UTF-8");

			if (StringUtils.isBlank(fileContent)) {
				log.info("民生批量代付回盘文件为空！");
			} else {
				log.info("File-Content: " + fileContent);
				String serialNoHead = String.format("%s%03d", recvDatas[0], Integer.valueOf(recvDatas[1]));
				String fileContents[] = fileContent.split("\n");
				for (int i = 1; i < fileContents.length; i++) {
					String fileLine = fileContents[i];
					String batchDetails[] = fileLine.split("\\|");
					MinshengBatchPayVo record = new MinshengBatchPayVo();
					String serialNo = String.format("%s%05d", serialNoHead, Integer.valueOf(batchDetails[0]));
					record.setSerialno(serialNo);
					record.setAccount_no(batchDetails[1]);
					record.setName(batchDetails[2]);
					record.setAmount(Double.valueOf(batchDetails[3]));
					record.setPayResult(batchDetails[4]);
					record.setRemark(batchDetails[5]);
					lists.add(record);
				}
			}
		}
		QueryBatchPayoutOrderMinshengContent content = new QueryBatchPayoutOrderMinshengContent();
		content.setBatchDate(recvDatas[0]);
		content.setBatchNo(recvDatas[1]);
		content.setBatchStat(recvDatas[2]);
		content.setMessage(recvDatas[3]);
		if ("1".equals(recvDatas[2])) {
			content.setCount(StringUtils.isBlank(recvDatas[4]) ? 0 : Integer.valueOf(recvDatas[4]));
			content.setAmount(StringUtils.isBlank(recvDatas[5]) ? 0 : new Double(recvDatas[5]));
			content.setSuccessCount(StringUtils.isBlank(recvDatas[6]) ? 0 : Integer.valueOf(recvDatas[6]));
			content.setSuccessAmount(StringUtils.isBlank(recvDatas[7]) ? 0 : new Double(recvDatas[7]));
			content.setFailCount(StringUtils.isBlank(recvDatas[8]) ? 0 : Integer.valueOf(recvDatas[8]));
			content.setFailAmount(StringUtils.isBlank(recvDatas[9]) ? 0 : new Double(recvDatas[9]));
			content.setUnknownCount(StringUtils.isBlank(recvDatas[10]) ? 0 : Integer.valueOf(recvDatas[10]));
			content.setUnknownAmount(StringUtils.isBlank(recvDatas[11]) ? 0 : new Double(recvDatas[11]));
			content.setLists(lists);
		}

		content.setRequestUrl(host + ":" + port);

		return content;
	}

	public CheckBatchPayoutOrderMinshengContent checkPayout(CheckBatchPayoutOrderMinshengParams checkBatchPayoutOrderMinshengParams)
			throws Exception {

		String host = checkBatchPayoutOrderMinshengParams.getHost();
		String port = checkBatchPayoutOrderMinshengParams.getPort();

		String header = checkBatchPayoutOrderMinshengParams.getHeader();
		byte[] headerBytes = header.getBytes();

		String body = checkBatchPayoutOrderMinshengParams.getBody();
		byte[] bodyBytes = body.getBytes("UTF-8");

		String keys = checkBatchPayoutOrderMinshengParams.getKeys();
		String vis = checkBatchPayoutOrderMinshengParams.getVis();
		String algorithm = checkBatchPayoutOrderMinshengParams.getAlgorithm();

		byte[] keyBytes = MinshengUtil.hex2bin(keys);

		Socket socket = new Socket(host, Integer.valueOf(port));

		int length = 0;
		OutputStream outputStream = socket.getOutputStream();

		byte[] format = new byte[1024 * 4];
		int format_length = 0;

		// 发报文头
		outputStream.write(headerBytes, 0, headerBytes.length);
		log.info(headerBytes.length + ": " + new String(headerBytes));
		System.arraycopy(headerBytes, 0, format, 0, headerBytes.length);
		format_length += headerBytes.length;

		// 发报文体
		outputStream.write(bodyBytes, 0, bodyBytes.length);
		log.info(bodyBytes.length + ": " + body);
		System.arraycopy(bodyBytes, 0, format, format_length, bodyBytes.length);
		format_length += bodyBytes.length;

		// 接收回调
		InputStream inputStream = socket.getInputStream();
		byte[] recvBuffer = new byte[226];
		length = inputStream.read(recvBuffer, 0, 226);
		log.info("recv data:\n[" + new String(recvBuffer, 0, length, "UTF-8") + "]");

		int bodyLength = Integer.valueOf(new String(recvBuffer, 0, 8));
		int offset = Integer.valueOf(new String(recvBuffer, 26, 6));
		log.info("Body-Length: " + bodyLength);
		log.info("Offset: " + offset);

		byte[] dt = new byte[14];
		System.arraycopy(recvBuffer, 32, dt, 0, 14);
		log.info("Time: " + new String(dt));

		byte[] recvAll = new byte[bodyLength];
		int recvd_length = 0;

		byte buffer[] = new byte[1024];
		while (recvd_length < bodyLength) {
			length = inputStream.read(buffer, 0, 1024);
			System.arraycopy(buffer, 0, recvAll, recvd_length, length);
			recvd_length += length;
			log.info("length: " + length + "\trecvd_length: " + recvd_length);
		}

		char fileFlag = (char) recvBuffer[22];
		log.info("File-Flag: " + fileFlag);

		int formatLength = bodyLength;

		// 文件标识
		if (fileFlag == '1') {
			formatLength = offset;
		}

		format = new byte[formatLength];
		// inputStream.read(format);
		System.arraycopy(recvAll, 0, format, 0, formatLength);
		byte[] decryptedFormat = MinshengUtil.decrypt(format, keys, vis, algorithm);
		String recvData = new String(decryptedFormat, "UTF-8");
		log.info("民生批量代付回调报文为：" + recvData);

		String recvDatas[] = recvData.split("\\|", -1);

		byte[] toMD5 = new byte[24 + 14 + decryptedFormat.length];
		System.arraycopy(keyBytes, 0, toMD5, 0, keyBytes.length);
		System.arraycopy(dt, 0, toMD5, 24, 14);
		System.arraycopy(decryptedFormat, 0, toMD5, 38, decryptedFormat.length);

		List<MinshengBatchPayVo> lists = new ArrayList<MinshengBatchPayVo>();
		Map<String, String> payResultMap = new HashMap<String, String>();

		if (fileFlag == '1') {
			int file_length = bodyLength - offset;
			byte[] file = new byte[file_length];
			System.arraycopy(recvAll, offset, file, 0, file_length);

			file = MinshengUtil.decrypt(file, keys, vis, algorithm);
			String fileContent = new String(file, "UTF-8");

			if (StringUtils.isBlank(fileContent)) {
				log.info("民生批量代付回盘文件为空！");
			} else {
				log.info("File-Content: " + fileContent);
				String serialNoHead = String.format("%s%03d", recvDatas[0], Integer.valueOf(recvDatas[1]));
				String fileContents[] = fileContent.split("\n");
				for (int i = 1; i < fileContents.length; i++) {
					String fileLine = fileContents[i];
					String batchDetails[] = fileLine.split("\\|");
					MinshengBatchPayVo record = new MinshengBatchPayVo();
					String serialNo = String.format("%s%05d", serialNoHead, Integer.valueOf(batchDetails[0]));
					record.setSerialno(serialNo);
					record.setAccount_no(batchDetails[1]);
					record.setName(batchDetails[2]);
					record.setAmount(Double.valueOf(batchDetails[3]));
					record.setPayResult(batchDetails[4]);
					record.setRemark(batchDetails[5]);
					lists.add(record);
					payResultMap.put(serialNo, batchDetails[4]);
				}
			}

		}

		CheckBatchPayoutOrderMinshengContent content = new CheckBatchPayoutOrderMinshengContent();
		content.setBatchDate(recvDatas[0]);
		content.setBatchNo(recvDatas[1]);
		content.setBatchStat(recvDatas[2]);
		content.setMessage(recvDatas[3]);
		if ("1".equals(recvDatas[2])) {
			content.setCount(StringUtils.isBlank(recvDatas[4]) ? 0 : Integer.valueOf(recvDatas[4]));
			content.setAmount(StringUtils.isBlank(recvDatas[5]) ? 0 : new Double(recvDatas[5]));
			content.setSuccessCount(StringUtils.isBlank(recvDatas[6]) ? 0 : Integer.valueOf(recvDatas[6]));
			content.setSuccessAmount(StringUtils.isBlank(recvDatas[7]) ? 0 : new Double(recvDatas[7]));
			content.setFailCount(StringUtils.isBlank(recvDatas[8]) ? 0 : Integer.valueOf(recvDatas[8]));
			content.setFailAmount(StringUtils.isBlank(recvDatas[9]) ? 0 : new Double(recvDatas[9]));
			content.setLists(lists);
			content.setPayResultMap(payResultMap);
		}

		content.setRequestUrl(host + ":" + port);
		return content;

	}

}
